<!-- 高德地图 -->
<template>
  <div style="display: flex">
    <div class="coordinate-input">
      <div v-for="(item, index) in coordinates" :key="index" class="input-row">
        <span class="row-num">第{{ index + 1 }}点：</span>
        <el-input v-model="item.lng" placeholder="经度" @change="validateCoordinate(index, 'lng')"
          :class="{ 'error-input': item.lngError }"></el-input>
        <el-input v-model="item.lat" placeholder="纬度" @change="validateCoordinate(index, 'lat')"
          :class="{ 'error-input': item.latError }"></el-input>
        <el-button @click="removeRow(index)" :disabled="coordinates.length <= 3" type="danger"
          size="small">删除</el-button>
      </div>
      <div class="button-group">
        <el-button @click="addRow" :disabled="coordinates.length >= 99" type="primary">新增坐标点</el-button>
        <el-button @click="createPolygonFromInput" :disabled="coordinates.length < 3"
          type="success">经纬度创建多边形</el-button>
      </div>
    </div>

    <div id="container" style="width: 1000px; height: 800px; border: 1px solid red"></div>
    <div class="input-card" style="width: 200px">
      <h4 style="margin-bottom: 10px; font-weight: 600">
        利用mouseTool绘制和编辑多边形
      </h4>
      <button class="btn" @click="drawPolygon" style="margin-bottom: 5px">
        绘制多边形
      </button>
      <button class="btn" @click="getPolygon" style="margin-bottom: 5px">
        获取多边形
      </button>
      <!-- <button class="btn" @click="createPolygon" style="margin-bottom: 5px">
        经纬度创建多边形
      </button> -->
      <button class="btn" @click="editorPolygon" style="margin-bottom: 5px" :disabled="!selectedPolygon">
        编辑多边形
      </button>
      <button class="btn" @click="saveEditedPolygon" style="margin-bottom: 5px" :disabled="!editMode">
        保存编辑
      </button>
      <button class="btn" @click="getarea" style="margin-bottom: 5px" :disabled="!selectedPolygon">获取多边形面积</button>
      <button class="btn" @click="clearPolygons" style="margin-top: 10px">
        清除所有多边形
      </button>
      <br />
      <el-switch v-model="showScale" @change="toggleScaleControl" inline-prompt active-text="显示比例尺"
        inactive-text="隐藏比例尺">
      </el-switch><br />
      <el-switch v-model="showZoom" @change="toggleZoomControl" inline-prompt active-text="显示缩放" inactive-text="隐藏缩放" />
      <br />
      <el-switch v-model="showControlBar" @change="toggleControlBar" inline-prompt active-text="显示视角控制器"
        inactive-text="隐藏视角控制器" />
      <br />
      <el-switch v-model="showHawkEye" @change="toggleHawkEyeControl" inline-prompt active-text="显示鹰眼图"
        inactive-text="隐藏鹰眼图" />
      <div class="polygon-list" style="width: 200px; margin-left: 20px">
        <h4>多边形列表</h4>
        <div v-for="(poly, index) in polygonList" :key="index" class="list-item"
          :style="{ color: poly.isSelected ? 'red' : '#333' }" @click="selectPolygon(poly)">
          多边形{{ index + 1 }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";

const map = ref(null);
const mouseTool = ref(null);
const polyEditor = ref(null);
// 新增响应式数据
const polygonList = ref([]);
const selectedPolygon = ref(null);
// 点位数组，绘制多边形，lng,lat
const path = ref([
  [113.55895, 32.675337],
  [113.565809, 32.675375],
  [113.565809, 32.670044],
  [113.55895, 32.669948],
]);

// 新增响应式变量
const showZoom = ref(true);
const showControlBar = ref(true);
const showHawkEye = ref(true);

const zoomTool = ref(null);
const controlBar = ref(null);
const hawkEye = ref(null);

const polygonOverlay = ref(null);
const editMode = ref(false);
const scale = ref(null);
let showScale = ref(true);
// 用户手动输入的坐标数据
const coordinates = ref(Array(3).fill().map(() => ({
  lng: '',
  lat: '',
  lngError: false,
  latError: false
})));

// 正则表达式
const LNG_REGEX = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,15})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,15}|180)$/;
const LAT_REGEX = /^(\-|\+)?([0-8]?\d{1}\.\d{0,15}|90\.0{0,15}|[0-8]?\d{1}|90)$/;

// 坐标合法性验证
const validateCoordinate = (index, type) => {
  const value = coordinates.value[index][type];
  const regex = type === 'lng' ? LNG_REGEX : LAT_REGEX;
  coordinates.value[index][`${type}Error`] = !regex.test(value);
};

// 新增行
const addRow = () => {
  if (coordinates.value.length < 99) {
    coordinates.value.push({
      lng: '',
      lat: '',
      lngError: false,
      latError: false
    });
  }
};

// 删除行
const removeRow = (index) => {
  if (coordinates.value.length > 3) {
    coordinates.value.splice(index, 1);
  }
};

// 创建多边形方法
const createPolygonFromInput = () => {
  // 先进行最终验证
  coordinates.value.forEach((item, index) => {
    validateCoordinate(index, 'lng');
    validateCoordinate(index, 'lat');
  });

  // 检查错误
  const errorRows = coordinates.value
    .map((item, index) => ({
      index: index + 1,
      hasError: item.lngError || item.latError
    }))
    .filter(item => item.hasError);

  if (errorRows.length > 0) {
    const errorMsg = `以下行数据有误：${errorRows.map(item => item.index).join(', ')}`;
    ElMessage.error(errorMsg);
    return;
  }

  // 生成路径数组
  const path = coordinates.value.map(item => [
    parseFloat(item.lng),
    parseFloat(item.lat)
  ]);

  // 创建多边形逻辑
  const polygon = new AMap.Polygon({
    path: path,
    strokeColor: "#1791fc",
    fillColor: "#1791fc",
    strokeWeight: 2
  });
  map.value.add([polygon]);

  // 加入多边形列表
  polygonList.value.push({
    instance: polygon,
    isSelected: false,
    originalColor: "#1791fc"
  });
};
onMounted(() => {
  setTimeout(() => {
    mapInit();
  }, 10);
});
window._AMapSecurityConfig = {
  securityJsCode: "37e8832772d3bc4749b81fdc0f6c7ccd",
};
function toggleScaleControl() {
  if (showScale.value) {
    scale.value.show();
  } else {
    scale.value.hide();
  }
}
const mapInit = () => {
  AMapLoader.load({
    key: "3157fcdc7011c18094780ea3d52b8215",
    version: "2.0",
    plugins: [],
  })
    .then((AMap) => {
      map.value = new AMap.Map("container", {
        viewMode: "3D",
        zoom: 15,
        center: [113.561218, 32.671247],
      });

      AMap.plugin(
        [
          // 插件列表
          "AMap.Scale",
          "AMap.ToolBar",
          "AMap.HawkEye",
          "AMap.ControlBar",
          "AMap.MapType",
          "AMap.MouseTool",
          "AMap.PolyEditor",
        ],
        function () {
          /**
           * 比例尺 show()开启 hide()关闭 \
           *  position:
           *  LT:左上角;
           *  RT:右上角;
           *  LB:左下角;
           *  RB:右下角;
           *  默认位置：LB
           *  offset:相对于角落的偏移量，默认值为[10,10]
           */
          // 比例尺
          scale.value = new AMap.Scale({
            position: "LB",
            offset: [10, 10]
          });
          map.value.addControl(scale.value);
          // 缩放控制器
          zoomTool.value = new AMap.ToolBar({
            position: "RB",
            offset: [40, 10],
          });
          map.value.addControl(zoomTool.value);
          // 旋转和俯视角度控制器
          controlBar.value = new AMap.ControlBar({
            position: "RB",
            offset: [10, 80],
          });
          map.value.addControl(controlBar.value);
          // 小地图
          /**
           * autoMove 是否随主图视口变化移动
           * showRectangle 是否显示视口矩形
           * showButton 是否显示打开关闭的按钮
           * opened 默认是否展开
           * mapStyle 缩略图要显示的地图自定义样式，如'amap://styles/dark'
           * layers 缩略图要显示的图层类型，默认为普通矢量地图
           * width 缩略图的宽度，同CSS，如'200px'
           * height 缩略图的高度，同CSS，如'200px'
           * offset 缩略图距离地图右下角的像素距离，如 [2,2]
           * borderStyle 缩略图的边框样式，同CSS，如"double solid solid double"
           * borderColor 缩略图的边框颜色，同CSS，如'silver'
           * borderRadius 缩略图的圆角半径，同CSS，如'5px'
           * borderWidth 缩略图的边框宽度，同CSS，如'2px'
           * buttonSize 缩略图的像素尺寸，同CSS，如'12px'
           */
          hawkEye.value = new AMap.HawkEye(
            {
              position: "LT",
              offset: [0, 0],
              opened: false,
            }
          )
          map.value.addControl(hawkEye.value);
          map.value.addControl(
            // 地图类型
            new AMap.MapType({
              defaultType: 1, // 0：底图 1：卫星图 默认：0
              showRoad: false, // 叠加路网
              showTraffic: false, //叠加交通路况
            })
          );
        }
      );

      mouseTool.value = new AMap.MouseTool(map.value);
      map.value.on("click", function (ev) {
        // 地图点击事件
      });
    })
    .catch((e) => {
      console.log(e);
    });
};
// 新增控制方法
const toggleZoomControl = (val) => {
  val ? zoomTool.value.show() : zoomTool.value.hide();
};
const toggleControlBar = (val) => {
  val ? controlBar.value.show() : controlBar.value.hide();
};
const toggleHawkEyeControl = (val) => {
  val ? hawkEye.value.show() : hawkEye.value.hide();
};
// 清除方法
const clearPolygons = () => {
  const overlays = map.value.getAllOverlays();
  overlays.forEach(overlay => {
    if (overlay instanceof AMap.Polygon) {
      map.value.remove(overlay);
    }
  });
  polygonOverlay.value = null; // 清空当前多边形引用
  polygonList.value = [];
  selectedPolygon.value = null;
};
// 绘制多边形
const drawPolygon = () => {
  if (mouseTool.value) {
    mouseTool.value.polygon({
      strokeColor: "#1791fc",
      strokeOpacity: 1,
      strokeWeight: 2,
      strokeOpacity: 1,
      fillColor: "#1791fc",
      fillOpacity: 0.1,
      strokeStyle: "solid",
    });
    mouseTool.value.on("draw", function (event) {

      // 获取绘制的覆盖物
      const polygon = event.obj;
      polygonOverlay.value = polygon;
      polygonList.value.push({
        instance: polygon,
        isSelected: false,
        originalColor: "#1791fc"
      });
    });
  }
};
// 选择多边形方法
const selectPolygon = (poly) => {
  const originalColor = poly.instance.getOptions().strokeColor;
  if (editMode.value) {
    if (!confirm("当前正在编辑，切换将丢失未保存的修改！")) return;
    saveEditedPolygon(); // 强制保存当前修改
  }
  // 重置所有多边形样式
  polygonList.value.forEach(p => {
    p.instance.setOptions({
      strokeColor: p.originalColor
    });
    p.isSelected = false;
  });

  // 设置选中样式
  poly.instance.setOptions({
    strokeColor: "#FF0000",
    strokeWeight: 3
  });

  // 更新选中状态
  poly.isSelected = true;
  poly.originalColor = originalColor;

  selectedPolygon.value = poly.instance;
};
const getarea = () => {
  if (selectedPolygon.value) {
    // 获取多边形的面积
    // console.log("多边形面积:", polygonOverlay.value.getArea(false) + '平方米');
    const area = selectedPolygon.value.getArea(false);
    console.log(`选中多边形面积：${area} 平方米`);
  }
};
// 获取绘制的多边形
const getPolygon = () => {
  // if (polygonOverlay.value) {
  //   // 在控制台中查看多边形的路径坐标
  //   console.log("多边形路径坐标:", polygonOverlay.value.getPath());
  // }
  // 获取地图上所有覆盖物
  const overlays = map.value.getAllOverlays();

  // 过滤出多边形对象
  const polygons = overlays.filter(overlay => {
    return overlay instanceof AMap.Polygon;
  });

  // 输出所有多边形路径
  polygons.forEach((polygon, index) => {
    console.log(`多边形${index + 1}路径坐标:`, polygon.getPath());
  });
};

// 创建多边形
const createPolygon = () => {
  var polygon = new AMap.Polygon({
    path: path.value,
    zIndex: 50,
    bubble: true,
    strokeColor: "#1791fc",
    fillColor: "#1791fc",
  });
  map.value.add([polygon]);
  // polygonOverlay.value = polygon;
  polygonList.value.push({
    instance: polygon,
    isSelected: false,
    originalColor: "#1791fc"
  });
};

// 多边形编辑
const editorPolygon = () => {
  if (selectedPolygon.value) {
    // 每次编辑前重置编辑器
    if (polyEditor.value) {
      polyEditor.value.close(); // 先关闭旧编辑器
      polyEditor.value = null;  // 清空引用
    }

    // 创建新编辑器实例
    polyEditor.value = new AMap.PolyEditor(
      map.value,
      selectedPolygon.value
    );

    polyEditor.value.open();
    editMode.value = true;
  }
};

// 保存编辑后的多边形
const saveEditedPolygon = () => {
  if (editMode.value && polyEditor.value) {
    // 获取当前选中项
    const selectedItem = polygonList.value.find(p => p.isSelected);

    polyEditor.value.close();
    editMode.value = false;
    polyEditor.value = null;

    // 恢复原始颜色
    if (selectedItem) {
      selectedItem.instance.setOptions({
        strokeColor: selectedItem.originalColor,
        strokeWeight: 2 // 恢复默认线宽
      });
    }
  }
};
</script>
<style>
.polygon-list {
  border: 1px solid #ddd;
  padding: 10px;
  max-height: 300px;
  overflow-y: auto;
}

.list-item {
  padding: 8px;
  cursor: pointer;
  border-bottom: 1px solid #eee;
  transition: all 0.3s;
}

.list-item:hover {
  background-color: #f5f5f5;
}

.coordinate-input {
  margin: 15px 0;
  border: 1px solid #ebeef5;
  padding: 15px;
  border-radius: 4px;
}

.input-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
  align-items: center;
}

.input-row .el-input {
  width: 80px;
}

.row-num {
  font-size: 12px;
  color: #909399;
  min-width: 50px;
}

.button-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 15px;

}

.error-input .el-input__inner {
  border-color: #f56c6c;
}

.error-input:hover .el-input__inner {
  border-color: #f56c6c;
}
</style>